Skip to content

feat(client): looksLikeV3Capabilities — drop the v2-downgrade footgun on capabilities-validation failure#475

Merged
bokelley merged 1 commit intomainfrom
bokelley/feat-looks-like-v3
May 3, 2026
Merged

feat(client): looksLikeV3Capabilities — drop the v2-downgrade footgun on capabilities-validation failure#475
bokelley merged 1 commit intomainfrom
bokelley/feat-looks-like-v3

Conversation

@bokelley
Copy link
Copy Markdown
Contributor

@bokelley bokelley commented May 3, 2026

Summary

Port of JS commit 27bd79d (#1201) to the Python SDK. Closes #461. Refs #452.

When get_adcp_capabilities fails strict schema validation but the response is structurally v3-shaped, surface the v3 validation error loudly instead of silently re-classifying the agent as v2 — which downstream tooling turns into a cascade of confusing "AdCP schema data for version v2.5 not found" errors that have nothing to do with the original wire-shape bug.

  • looks_like_v3_capabilities(data) (in src/adcp/capabilities.py, also re-exported from top-level adcp) checks for any one v3 signal: the adcp envelope, supported_protocols array, or any v3 protocol-level block (account, media_buy, signals, creative, brand, governance, sponsored_intelligence, compliance_testing).
  • Arrays are explicitly rejected via a small _is_plain_object helper so adcp: [] / media_buy: [] don't false-positive (mirrors the JS isPlainObject defense).
  • ADCPClient.refresh_capabilities distinguishes parse failure (the _parse_response "Failed to parse response:" prefix) from transport failure: parse failures re-fetch the raw dict from the adapter and run the heuristic; transport failures fall straight through to the original "Failed to fetch capabilities" path so the existing failure-raises test stays green.

Test plan

  • 23 unit tests for the heuristic (positive + negative shapes, including the array-rejection defense)
  • 4 wire-up tests on refresh_capabilities:
    • clean v3 → parses successfully
    • broken v3 with one shape bug → loud v3-flavor error, error message mentions v3 and never v2.5
    • non-v3-shaped response → falls through to existing transport-error path
    • transport failure with no data → still raises "Failed to fetch capabilities", adapter called exactly once (no extra probe)
  • ruff check clean on touched files
  • mypy clean on src/adcp/capabilities.py + src/adcp/client.py
  • Full tests/ suite: 3065 passed, 18 skipped, 1 xfailed (no regressions)

🤖 Generated with Claude Code

…gun on capabilities-validation failure

Port of JS commit 27bd79d (#1201). When `get_adcp_capabilities` fails strict
schema validation but the response is structurally v3-shaped, surface the
v3 validation error loudly instead of silently re-classifying the agent as
v2 — which downstream tooling turns into a cascade of confusing
"AdCP schema data for version v2.5 not found" errors that have nothing to
do with the original wire-shape bug.

`looks_like_v3_capabilities(data)` checks for any one v3 signal: the `adcp`
envelope, `supported_protocols` array, or any v3 protocol-level block
(`account`, `media_buy`, `signals`, `creative`, `brand`, `governance`,
`sponsored_intelligence`, `compliance_testing`). Arrays are explicitly
rejected via the `_is_plain_object` helper so `adcp: []` / `media_buy: []`
don't false-positive.

`ADCPClient.refresh_capabilities` now distinguishes parse failure (the
`_parse_response` "Failed to parse response:" prefix) from transport
failure: parse failures re-fetch the raw dict from the adapter and run
the heuristic; transport failures fall straight through to the original
"Failed to fetch capabilities" path so the existing failure-raises test
keeps passing.

Closes #461. Refs #452.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@bokelley bokelley merged commit 385dc80 into main May 3, 2026
14 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

feat(client): looksLikeV3Capabilities — drop the v2-downgrade footgun on capabilities-validation failure

1 participant